package com.myschool.server.dao.support;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class GenericDaoHibernate<T> extends HibernateDaoSupport
		implements GenericDao<T> {
	/** Logging instance */
	protected static final Log LOG = LogFactory
			.getLog(GenericDaoHibernate.class);
	protected final Class<T> persistentClass;

	/**
	 * Constructor that takes in a class to determine what type of entity is to
	 * be persisted.
	 * 
	 * @param persistentClass
	 *            the class type which is to be persisted.
	 */
	public GenericDaoHibernate(final Class<T> persistentClass) {
		this.persistentClass = persistentClass;
	}

	/**
	 * {@inheritDoc}
	 */
	public List<T> getAll() {
		return getHibernateTemplate().loadAll(persistentClass);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean exists(final Long id) {
		final T entity = (T) getHibernateTemplate().get(persistentClass, id);
		return entity != null;
	}

	/**
	 * {@inheritDoc}
	 */
	public void remove(final T object) {
		getHibernateTemplate().delete(object);
	}

	/** {@inheritDoc} */
	@Override
	public void flush() {
		getHibernateTemplate().flush();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public T get(final Long id) {
		final T entity = (T) getHibernateTemplate().get(persistentClass, id);

		/*
		 * TODO - Should the DAO throw the exception below if the object is not
		 * found?
		 * 
		 * if (entity == null) { throw new
		 * ObjectRetrievalFailureException(persistentClass, id); }
		 */

		return entity;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public T remove(final Long id) {
		final T object = this.get(id);

		if (object != null) {
			getHibernateTemplate().delete(object);
		}

		return object;
	}

	/**
	 * Call this when method paramaters are wrong. Will throw an
	 * {@link IllegalArgumentException}.
	 * 
	 * @param methodName
	 *            the name of the called method
	 * @throws IllegalArgumentException
	 */
	public void blankParameterError(String methodName) {
		String error = String.format("%s: %s parameters must not be blank",
				methodName, persistentClass.getSimpleName());
		LOG.warn(error);
		throw new IllegalArgumentException();
	}
}
